import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.IntBuffer;


import javax.media.opengl.*;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import com.jogamp.common.nio.Buffers;

import com.jogamp.opengl.util.*;

public class joglTest3 implements GLEventListener {
	private static JFrame appFrame;
	private static SceneGraphNode sceneGraphRoot;
	private static boolean pickNextFrame;
	private static Point pickedPoint;
	private static double left, right, top, bottom;
	private static int displayListId = -1;
	
	public static void main(String[] args) {
		GLProfile.initSingleton();
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				(new joglTest3()).createAndShowGUI();
			}
		});
	}
	
	private void createAndShowGUI()
	{
		GLProfile glp = GLProfile.getDefault();
		GLCapabilities caps = new GLCapabilities(glp);
		GLCanvas canvas = new GLCanvas(caps);
		canvas.addGLEventListener(this);
	
		canvas.addMouseListener(new MouseAdapter() 
		{
			public void  mousePressed(MouseEvent e) 
			{
				pickNextFrame=true;
				pickedPoint = new Point(e.getX(), e.getY());
			}
		
	});
		
		//sceneGraphRoot = new Triforce();
		sceneGraphRoot = SeirpinskiTriangle.create(8);
		
		appFrame = new JFrame("Jogl Test 3");
		appFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		appFrame.setMinimumSize(new Dimension(256,256));
		appFrame.add(canvas);
		appFrame.pack();
		
		//what? why?
		if(Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) 
			appFrame.setExtendedState(appFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
		appFrame.setVisible(true);
		
	}

	@Override
	public void display(GLAutoDrawable drawable) {
		GL2 gl = drawable.getGL().getGL2();
		gl.glClear(GL.GL_COLOR_BUFFER_BIT);
		
		if(pickNextFrame) 
		{
				GLU glu = GLU.createGLU(gl);
			int viewport[] = new int[4];
			gl.glGetIntegerv(GL.GL_VIEWPORT, viewport,0);
			gl.glMatrixMode(GL2.GL_PROJECTION);
			gl.glPushMatrix();
			gl.glLoadIdentity();
			glu.gluPickMatrix(pickedPoint.x, (double)(viewport[3] - pickedPoint.y),1,1,viewport,0);
			gl.glOrtho(left, right, bottom, top, -1,1);
			gl.glMatrixMode(GL2.GL_MODELVIEW);
			System.out.println(sceneGraphRoot.getPicked(drawable));
			gl.glMatrixMode(GL2.GL_PROJECTION);
			gl.glPopMatrix();
			gl.glMatrixMode(GL2.GL_MODELVIEW);
			
			pickNextFrame=false;
		}
		if(displayListId == -1)
		{
			displayListId = 1;
			gl.glNewList(displayListId,GL2.GL_COMPILE_AND_EXECUTE);
			sceneGraphRoot.render(drawable);
			gl.glEndList();
			
		}
		else
			gl.glCallList(displayListId);
		//sceneGraphRoot.render(drawable);
		//sceneGraphRoot.rotation++;
		gl.glRotatef(1,0,0,1);
	}

	@Override
	public void dispose(GLAutoDrawable arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init(GLAutoDrawable drawable) {
		GL2 gl = drawable.getGL().getGL2();
		gl.glClearColor(0,0,0,0);
		IntBuffer selectBuffer = Buffers.newDirectIntBuffer(3);
		gl.glSelectBuffer(selectBuffer.capacity(), selectBuffer);
		FPSAnimator fps = new FPSAnimator(drawable,30);
		fps.start();
		
		
	}

	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int width,int height) {
		//preserve aspect ratio 
		
		final double UNIT = 4;
		
		if(width<height)
		{
			left = -UNIT/2;
			right = UNIT/2;
			top = (double) height/width * UNIT/2;
			bottom = -top;
		}
		else
		{
			top = UNIT/2;
			bottom = -UNIT/2;
			right = (double) width/height * UNIT/2;
			left = -right;
		}
		
		GL2 gl = drawable.getGL().getGL2();
		gl.glMatrixMode(GL2.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glOrtho(left,right,bottom,top,-1,1);
		gl.glMatrixMode(GL2.GL_MODELVIEW);
	}
	
}
